#
# 	Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
#
#	This file is part of simavr.
#
#	simavr is free software: you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation, either version 3 of the License, or
#	(at your option) any later version.
#
#	simavr is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#
#	You should have received a copy of the GNU General Public License
#	along with simavr.  If not, see <http://www.gnu.org/licenses/>.

SHELL=/bin/bash

# Set your AVR Path here
AVR_ROOT 	:= /usr/lib/avr
#AVR_ROOT 	:= ../WinAVR

UNAME := $(shell uname -s)

cores		= ${wildcard cores/*.c}
cores_o 	= ${patsubst cores/%.c, obj/%.o, ${cores}}
sim		= ${wildcard sim/sim_*.c} ${wildcard sim/avr_*.c}
sim_o 	= ${patsubst sim/%.c, obj/%.o, ${sim}}

CC 		?= gcc
AR 		?= ar
RANLIB 	?= ranlib
MKDIR		?= mkdir -p

VPATH		= cores
VPATH		+= sim

IPATH		= sim
IPATH		+= .

CFLAGS	+= -g --std=gnu99 -O2 
CFLAGS	+= ${patsubst %,-I%,${subst :, ,${IPATH}}}


ifeq ($(UNAME), Linux)
AVR_INC 	:= ${AVR_ROOT}
AVR 		:= avr-
CFLAGS 	+= -fPIC
else
AVR_INC 	:= ${shell echo ${AVR_ROOT} | sed 's/\(.\):/\/cygdrive\/\1\//'}/avr
AVR 		:= ${shell echo ${AVR_ROOT} | sed 's/\(.\):/\/cygdrive\/\1\//'}/bin/avr-
endif

OBJ 		= obj

all:	obj config libsimavr.a

${OBJ}/sim_%.o : cores/sim_%.c
	@gcc $(CFLAGS) -MD \
		-I${AVR_INC}/include/ \
		$<  -c -o $@
	@echo CORE $<

${OBJ}/%.o: %.c
	@gcc $(CFLAGS) -MD \
		$<  -c -o $@
	@echo CC $<

${OBJ}: 
	@mkdir -p ${OBJ}

# include the dependency files generated by gcc, if any
-include ${wildcard ${OBJ}/*.d}

libsimavr.a	:	${cores_o}
libsimavr.a	:	${sim_o}
	@echo AR $@
	@ar cru $@ $^
	@ranlib $@
	
clean:
	rm -rf obj *.a
	
config: ${OBJ}/cores.deps sim_core_config.h sim_core_decl.h

sim_core_config.h ${OBJ}/cores.deps: $(cores) Makefile
	@echo $(UNAME)
	@echo CONF $@
	@conf=""; decl=""; array=""; \
	mkdir -p ${OBJ} ; echo >${OBJ}/cores.deps ; \
	for core in cores/*.c ; do \
		file=$$core; global=$${core/cores\/sim_}; global=$${global/.c}; \
		upper=$$(echo $$global|tr '[a-z]' '[A-Z]'); \
		if $(CC) -E $(CFLAGS) -I$(AVR_INC)/include $$file \
			>/dev/null 2>&1 ; then \
			conf+="#define CONFIG_$$upper 1\n"; \
			obj=$${file/.c/.o} ; obj=$${obj/cores\/}; \
			printf "\$libsimavr.a: \$${OBJ}/$$obj\n">>${OBJ}/cores.deps ; \
		else \
			echo WARNING $$file did not compile, check your avr-gcc toolchain; \
		fi \
	done ; \
	( printf "// Autogenerated do not edit\n"; \
	  printf "#ifndef __SIM_CORE_CONFIG_H__\n#define __SIM_CORE_CONFIG_H__\n\n"; \
	  printf "$$conf\n"; \
	  printf "#endif\n"; \
	) >sim_core_config.h

sim_core_decl.h: sim_core_config.h $(cores) Makefile
	@echo $(UNAME)
	@echo CONF $@
	@decl=""; array=""; \
	for core in $$(grep -r avr_kind_t cores/|awk -F '[ :]' '{print $$1 "=" $$3;}') ; do \
		file=$${core/=*}; global=$${core/*=}; \
		upper=$${file/cores\/sim_}; upper=$${upper/.c}; \
		upper=$$(echo $$upper|tr '[a-z]' '[A-Z]'); \
		decl+="#if CONFIG_$$upper\nextern avr_kind_t $$global;\n#endif\n"; \
		array+="#if CONFIG_$$upper\n\t&$$global,\n#endif\n"; \
	done ; \
	( printf "// Autogenerated do not edit\n"; \
	  printf "#ifndef __SIM_CORE_DECL_H__\n#define __SIM_CORE_DECL_H__\n\n"; \
	  printf "#include \"sim_core_config.h\"\n";\
	  printf "$$decl\n" ;  \
	  printf "extern avr_kind_t * avr_kind[];\n"; \
	  printf "#ifdef AVR_KIND_DECL\navr_kind_t * avr_kind[] = {\n$$array\tNULL\n};\n#endif\n"; \
	  printf "#endif\n"; \
	) >sim_core_decl.h

-include ${OBJ}/cores.deps

	
